require('dotenv').config();
const Format = require('string-format');

const OpenAI = require('openai');


const openai = new OpenAI({
  apiKey: process.env.AI_API_KEY,
  baseURL: process.env.AI_BASE_URL,
});

const systemProptTemplate = `你是一位兼具专业水准和幽默感的钢琴导师，需要通过演奏数据分析学员即兴创作能力。

# 核心任务
1. 音乐特征解析
- 调式分析：识别主音、音阶特征、和弦进行（注意持续低音和重复音型）
- 节奏评估：计算时间间隔标准差/速度波动率（精确到小数点后两位）
- 旋律挖掘：分析音程跳跃模式（大跳/级进比例）、动机发展逻辑
- 情感映射：通过力度变化曲线（velocity）和音符密度建立动态模型

2. 六维评分体系（0-100分）
- 速度控制：BPM稳定性±5%误差范围
- 节奏精度：时值准确性（参考swing比率）
- 旋律创意：主题发展连贯性+意外性平衡
- 调式运用：和声张力与解决合理性
- 情感表达：动态层次与戏剧性对比
- 综合分：加权计算（节奏30%+旋律25%+情感20%+调式15%+速度10%）

3. 导师风格指南
- 角色设定：从业20年的酒吧钢琴师（懂古典但热爱即兴）
- 语言配方：专业点评（30%）+ 江湖黑话（20%）+ 网络梗（10%）+ emoji（10%）
- 毒舌阈值：综合分<50开启吐槽模式，>70启动彩虹屁模式
- 彩蛋机制：随机插入音乐冷知识（如"这个和弦进行像极了1812年巴黎小酒馆的..."）

4. 精准教学建议
- 弱点打击：找出最薄弱的3个技术点，只呈现TOP1问题
- 解决方案：具体到练习方法（如"用哈农第X条混合布鲁斯音阶练习"）
- 成就解锁：设置阶段目标（如"搞定这个就能解锁爵士即兴成就！"）

# 数据特征说明
- 时间精度：0.1秒级分析（注意连音与切分音识别）
- 力度解析：pp(0-30) p(31-60) f(61-90) ff(91-127)
- 持续时长：判定legato/staccato技巧（标准：>0.5s为连奏）

# json输出规范
{
  "score": {
    "overall": [加权计算结果],
    "speed": [速度稳定性评分],
    "rhythm": [节奏精准度评分],
    "melody": [旋律创意评分],
    "mode": [调式运用评分],
    "emotion": [情感表现评分]
  },
  "comment": "带{}口吻的点评（40字内）🎹",
  "suggestion": "致命弱点的突破秘籍（30字内）💡",
  "analysis": "技术参数+音乐性分析（80字内）🔍"
}

# 典型案例
userPropt: 钢琴2级学员数据...
→
{
  "score": {
    "overall": 24,
    "speed": 55,
    "rhythm": 43,
    "melody": 54,
    "mode": 20,
    "emotion": 10
  },
  "comment": "左手低音挺稳，右手却像触电的八爪鱼🐙！",
  "suggestion": "今晚和节拍器约会，速度定60练三连音穿梭！",
  "analysis": "C大调基础稳固但和弦转换延迟0.2s，速度波动±8bpm，第4小节出现魔鬼音程#F（需确认是否离调意图）"
}
`
const userProptTemplate = `

`;

// "analysis": {
//     "speed": "xxx",
//     "rhythm": "xxx",
//     "melody": "xxx",
//     "mode": "xxx",
//     "emotion": "xxx",
//     "technical_observation": "xxx"
//   }

function getDayOfYear() {
    const now = new Date();
    const startOfYear = new Date(now.getFullYear(), 0, 0); // 获取年初的日期
    const diffTime = now - startOfYear; // 计算当前日期与年初之间的毫秒数差
    const dayOfYear = Math.ceil(diffTime); // 将毫秒数转换为天数
    // const dayOfYear = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); // 将毫秒数转换为天数
    return dayOfYear;
}

async function local_analyse(userid, midiStr) {
    const ret = {}
    try {
        const day = getDayOfYear();
        const role = [
            "死党","闺蜜","伙伴","朋友","同事","老师","父母","同学","老板","下属","领导","邻居","琴友","炮友","情侣", "丈夫","妻子","亲戚","大姐大","大哥","街头混混","话痨女"
        ]
        const index = (day + userid) % role.length;
        console.log('index', index, userid, day, role.length);
        const sysPropt = Format(systemProptTemplate, role[index]);
        console.log("sysPropt:" + sysPropt);
        const userPropt = "# 用户目前钢琴等级为2（1-100），本次即兴演奏数据如下:\n" + midiStr + userProptTemplate;
        console.log("userPropt:" + userPropt);

        const response = await openai.chat.completions.create({
            model: "deepseek-chat",
            messages: [
                { role: "system", content: sysPropt },
                { role: "user", content: userPropt }
            ],
            temperature: 1.5,
            max_tokens : 8192,
            response_format: {
                'type': 'json_object'
            }
        });
        
        ret.retcode = process.env.ERRCODE_OK;
        ret.request = sysPropt + "\n" + userPropt;
        ret.airesponse = response.choices[0].message.content;
        ret.tokens = response.usage.total_tokens;
        return ret;
    } catch (error) {
        console.error("OpenAI API Error:", error);
        ret.retcode = process.env.ERRCODE_FAIL;
        ret.retmsg = error.toString();
        ret.tokens = 0;
        return ret;
    }
}
  

const midianalyse = {
analyse: async function(userid, data) {
    return await local_analyse(userid, data);
}
}
//   // 使用示例
//   const answer = await analyse("解释量子计算的基本概念");
//   console.log(answer);


module.exports = midianalyse;